با تسلط بر User Timing API، معیارهای عملکردی سفارشی و معنادار ایجاد کنید. فراتر از معیارهای حیاتی وب بروید تا تنگناها را شناسایی و تجربه کاربری را بهینه کنید.
تسلط بر عملکرد فرانتاند: بررسی عمیق User Timing API
در چشمانداز دیجیتال مدرن، عملکرد فرانتاند یک مزیت نیست؛ بلکه یک نیاز اساسی برای موفقیت است. برای مخاطبان جهانی، یک وبسایت کند و غیرپاسخگو میتواند منجر به نارضایتی کاربر، کاهش تعامل و تأثیر منفی مستقیم بر نتایج کسبوکار شود. ما معیارهای استاندارد عالی مانند Core Web Vitals (Largest Contentful Paint, First Input Delay, Cumulative Layout Shift) را داریم که درک پایهای از تجربه کاربری به ما میدهند. با این حال، این معیارها، هرچند حیاتی، تنها بخشی از داستان را روایت میکنند.
عملکرد ویژگیهای خاص برنامه چطور؟ چقدر طول میکشد تا نتایج جستجو پس از تایپ یک عبارت توسط کاربر نمایش داده شوند؟ کامپوننت پیچیده مصورسازی داده شما چقدر زمان برای رندر شدن پس از دریافت داده از API نیاز دارد؟ یک ویژگی جدید چگونه بر سرعت انتقال مسیر (route transitions) در برنامه تکصفحهای (SPA) شما تأثیر میگذارد؟ معیارهای استاندارد نمیتوانند به این سؤالات جزئی و حیاتی برای کسبوکار پاسخ دهند. اینجاست که User Timing API وارد میشود و به توسعهدهندگان این قدرت را میدهد تا اندازهگیریهای عملکردی سفارشی و با دقت بالا، متناسب با برنامههای منحصربهفرد خود ایجاد کنند.
این راهنمای جامع شما را با تمام آنچه برای بهرهگیری از User Timing API نیاز دارید، از مفاهیم پایهای نشانهها (marks) و اندازهگیریها (measures) گرفته تا تکنیکهای پیشرفته با استفاده از PerformanceObserver، آشنا خواهد کرد. در پایان، شما مجهز خواهید شد تا فراتر از معیارهای عمومی بروید و داستان عملکرد منحصربهفرد برنامه خود را روایت کنید.
Performance API چیست؟ یک زمینه گستردهتر
قبل از اینکه عمیقاً به User Timing بپردازیم، مهم است بدانیم که این ابزار بخشی از مجموعه بزرگتری از ابزارهاست که به طور کلی به عنوان Performance API شناخته میشود. این API مرورگر، دسترسی به دادههای زمانبندی با دقت بالا مربوط به پیمایش، بارگذاری منابع و موارد دیگر را فراهم میکند. شیء سراسری `window.performance` نقطه ورود شما به این مجموعه ابزار قدرتمند است.
Performance API از چندین رابط تشکیل شده است، از جمله:
- Navigation Timing: اطلاعات زمانبندی دقیقی درباره فرآیند پیمایش سند ارائه میدهد، مانند زمان صرفشده برای جستجوی DNS، TCP handshakes و دریافت اولین بایت.
- Resource Timing: دادههای زمانبندی شبکه دقیقی برای هر منبع بارگذاریشده توسط صفحه، از جمله تصاویر، اسکریپتها و فایلهای CSS، ارائه میدهد.
- Paint Timing: زمانهای First Paint و First Contentful Paint را در اختیار قرار میدهد.
- User Timing: که تمرکز مقاله ما بر آن است، به توسعهدهندگان اجازه میدهد تا مهرهای زمانی سفارشی خود (marks) را ایجاد کرده و مدت زمان بین آنها (measures) را اندازهگیری کنند.
این APIها با هم کار میکنند تا یک دید جامع از عملکرد برنامه شما ارائه دهند. هدف امروز ما تسلط بر بخش User Timing است که به ما قدرت اضافه کردن نقاط بازرسی سفارشی خودمان به این خط زمانی عملکرد را میدهد.
مفاهیم اصلی: Marks و Measures
User Timing API به طرز فریبندهای ساده است و حول دو مفهوم اساسی میچرخد: نشانهها (marks) و اندازهگیریها (measures). آن را مانند استفاده از یک کرونومتر در نظر بگیرید. شما یک دکمه را برای ثبت زمان شروع فشار میدهید و دوباره آن را برای ثبت زمان پایان فشار میدهید. مدت زمان بین این دو فشار، اندازهگیری شماست.
ایجاد نشانههای عملکرد: `performance.mark()`
یک 'mark' یک مهر زمانی با نام و با وضوح بالا است که در یک نقطه خاص از اجرای برنامه شما ثبت میشود. مانند کاشتن یک پرچم در خط زمانی عملکرد شماست. شما میتوانید هر تعداد mark که برای شناسایی لحظات کلیدی در سفر کاربر یا چرخه حیات کامپوننت نیاز دارید، ایجاد کنید.
نحو آن ساده است:
performance.mark(markName, [markOptions]);
markName: یک رشته که نام منحصربهفرد نشانهی شما را نشان میدهد. نامهای توصیفی انتخاب کنید!markOptions(اختیاری): یک شیء که میتواند شامل یک ویژگیdetailبرای پیوست کردن فرادادههای اضافی، و یکstartTimeبرای مشخص کردن یک مهر زمانی سفارشی باشد.
مثال پایه: نشانهگذاری یک رویداد
فرض کنید میخواهیم شروع یک فراخوانی تابع مهم را نشانهگذاری کنیم.
function processLargeDataset() {
// Plant a flag right before the heavy work begins
performance.mark('processLargeDataset:start');
// ... heavy computational logic ...
console.log('Dataset processing complete.');
// Plant another flag when it's done
performance.mark('processLargeDataset:end');
}
processLargeDataset();
در این مثال، ما دو مهر زمانی در خط زمانی عملکرد مرورگر ایجاد کردهایم: `processLargeDataset:start` و `processLargeDataset:end`. در حال حاضر، اینها فقط نقاطی در زمان هستند. قدرت واقعی آنها زمانی آشکار میشود که از آنها برای ایجاد یک اندازهگیری استفاده کنیم.
افزودن زمینه با ویژگی `detail`
گاهی اوقات، یک مهر زمانی به تنهایی کافی نیست. ممکن است بخواهید زمینه اضافی در مورد آنچه در آن لحظه اتفاق میافتد را شامل کنید. ویژگی `detail` برای این کار عالی است. این ویژگی میتواند هر دادهای را که به صورت ساختاری قابل کلون شدن باشد (مانند اشیاء، آرایهها، رشتهها، اعداد) در خود نگه دارد.
تصور کنید ما در حال نشانهگذاری شروع رندر یک کامپوننت هستیم و میخواهیم بدانیم چه تعداد آیتم در حال رندر شدن است.
function renderProductList(products) {
const itemCount = products.length;
performance.mark('ProductList:render:start', {
detail: {
itemCount: itemCount,
source: 'initial-load'
}
});
// ... component rendering logic ...
performance.mark('ProductList:render:end');
}
const sampleProducts = new Array(1000).fill(0);
renderProductList(sampleProducts);
این زمینه اضافی هنگام تحلیل دادههای عملکردی در آینده بسیار ارزشمند است. برای مثال، شما میتوانید زمانهای رندر را با تعداد آیتمها مرتبط کنید تا ببینید آیا یک رابطه خطی یا نمایی وجود دارد.
ایجاد اندازهگیریهای عملکرد: `performance.measure()`
یک 'measure' مدت زمان بین دو نقطه زمانی را ثبت میکند. این محاسبهای است که به شما میگوید یک کار "چقدر طول کشید". معمولاً، شما زمان بین دو نشانه سفارشی خود را اندازهگیری خواهید کرد.
نحو آن چند تنوع دارد:
performance.measure(measureName, startMarkOrOptions, [endMark]);
measureName: یک رشته که نام منحصربهفرد اندازهگیری شما را نشان میدهد.startMarkOrOptions(اختیاری): یک رشته با نام نشانه شروع. همچنین میتواند یک شیء گزینهها با `start`، `end`، `duration` و `detail` باشد.endMark(اختیاری): یک رشته با نام نشانه پایان.
مثال پایه: اندازهگیری مدت زمان یک تابع
بیایید بر اساس مثال `processLargeDataset` خود پیش برویم و واقعاً اندازهگیری کنیم که چقدر طول کشید.
function processLargeDataset() {
performance.mark('processLargeDataset:start');
// ... heavy computational logic ...
performance.mark('processLargeDataset:end');
// Now, create the measure
performance.measure(
'processLargeDataset:duration',
'processLargeDataset:start',
'processLargeDataset:end'
);
}
processLargeDataset();
پس از اجرای این کد، بافر عملکرد مرورگر شامل یک ورودی جدید به نام `processLargeDataset:duration` خواهد بود. این ورودی یک ویژگی `duration` خواهد داشت که زمان دقیق سپری شده بین نشانههای شروع و پایان را بر حسب میلیثانیه نگه میدارد.
سناریوهای اندازهگیری پیشرفته
متد `measure()` بسیار انعطافپذیر است. شما همیشه مجبور نیستید دو نشانه ارائه دهید.
- از شروع پیمایش تا یک نشانه: شما میتوانید زمان را از زمانی که پیمایش صفحه شروع شده تا یکی از نشانههای سفارشی خود اندازهگیری کنید. این برای اندازهگیری مواردی مانند "زمان تا کامپوننت تعاملی" فوقالعاده مفید است.
// Measure from navigation start until the main component is ready performance.measure('timeToInteractiveHeader', 'navigationStart', 'headerComponent:ready'); - از یک نشانه تا کنون: اگر `endMark` را حذف کنید، اندازهگیری از `startMark` شما تا زمان فعلی محاسبه خواهد شد.
// Measure from the start mark until this line of code is executed performance.measure('timeSinceDataRequest', 'api:fetch:start'); - استفاده از شیء گزینهها: شما همچنین میتوانید یک شیء پیکربندی برای تعریف اندازهگیری ارسال کنید، که برای افزودن یک ویژگی `detail` مفید است.
performance.measure('complexRender:duration', { start: 'complexRender:start', end: 'complexRender:end', detail: { renderType: 'canvas' } });
دسترسی و پاک کردن ورودیهای عملکرد
ایجاد نشانهها و اندازهگیریها تنها نیمی از کار است. شما به راهی برای بازیابی این دادهها برای تحلیل آنها نیاز دارید. شیء `performance` چندین متد برای این کار فراهم میکند.
performance.getEntries(): آرایهای از تمام ورودیهای عملکرد در بافر را برمیگرداند (شامل زمانبندی منابع، زمانبندی پیمایش و غیره).performance.getEntriesByType(type): آرایهای از ورودیهای یک نوع خاص را برمیگرداند. شما اغلب از `performance.getEntriesByType('mark')` و `performance.getEntriesByType('measure')` استفاده خواهید کرد.performance.getEntriesByName(name, [type]): آرایهای از ورودیها با یک نام خاص (و به صورت اختیاری، یک نوع خاص) را برمیگرداند.
مثال: ثبت اندازهگیریها در کنسول
// After running our previous examples...
const allMeasures = performance.getEntriesByType('measure');
console.log(allMeasures);
// A measure entry object looks something like this:
// {
// "name": "processLargeDataset:duration",
// "entryType": "measure",
// "startTime": 12345.67,
// "duration": 150.89
// }
const specificMeasure = performance.getEntriesByName('processLargeDataset:duration');
console.log(`Processing took: ${specificMeasure[0].duration}ms`);
مهم: پاکسازی بافر عملکرد
بافر عملکرد مرورگر نامحدود نیست. برای جلوگیری از نشت حافظه و مرتبط نگه داشتن اندازهگیریهای خود، بهترین کار این است که نشانهها و اندازهگیریهایی را که ایجاد کردهاید، پس از اتمام کار با آنها پاک کنید.
performance.clearMarks([name]): تمام نشانهها یا فقط نشانههایی با نام مشخص را پاک میکند.performance.clearMeasures([name]): تمام اندازهگیریها یا فقط اندازهگیریهایی با نام مشخص را پاک میکند.
یک الگوی رایج این است که دادهها را بازیابی کرده، پردازش یا ارسال کنید و سپس آنها را پاک کنید.
function analyzeAndClear() {
const myMeasures = performance.getEntriesByName('processLargeDataset:duration');
// Send myMeasures to an analytics service...
sendToAnalytics(myMeasures);
// Clean up to free memory
performance.clearMarks('processLargeDataset:start');
performance.clearMarks('processLargeDataset:end');
performance.clearMeasures('processLargeDataset:duration');
}
موارد استفاده عملی و واقعی برای User Timing
اکنون که مکانیک کار را درک کردیم، بیایید بررسی کنیم که چگونه User Timing API را برای حل چالشهای عملکردی در دنیای واقعی به کار ببریم. این مثالها مستقل از فریمورک هستند و میتوانند برای هر پشته فرانتاندی تطبیق داده شوند.
۱. اندازهگیری مدت زمان فراخوانیهای API
درک اینکه برنامه شما چقدر برای داده منتظر میماند، حیاتی است. شما به راحتی میتوانید منطق واکشی داده خود را با نشانهها و اندازهگیریها بپوشانید.
async function fetchUserData(userId) {
const markStart = `api:getUser:${userId}:start`;
const markEnd = `api:getUser:${userId}:end`;
const measureName = `api:getUser:${userId}:duration`;
performance.mark(markStart);
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return await response.json();
} catch (error) {
console.error('Fetch error:', error);
// You can even add details about errors!
performance.mark(markEnd, { detail: { status: 'error', message: error.message } });
} finally {
// Ensure the end mark and measure are always created
if (performance.getEntriesByName(markEnd).length === 0) {
performance.mark(markEnd, { detail: { status: 'success' } });
}
performance.measure(measureName, markStart, markEnd);
}
}
fetchUserData('123');
این الگو زمانبندی دقیقی برای هر فراخوانی API فراهم میکند و به شما امکان میدهد تا نقاط پایانی کند را مستقیماً از دادههای کاربران واقعی شناسایی کنید.
۲. ردیابی زمان رندر کامپوننتها در SPAها
برای فریمورکهایی مانند React، Vue یا Angular، اندازهگیری زمانی که یک کامپوننت برای نصب (mount) و رندر شدن نیاز دارد، یک مورد استفاده اصلی است. این به شناسایی کامپوننتهای پیچیدهای که ممکن است برنامه شما را کند کنند، کمک میکند.
مثال با هوکهای React:
import React, { useLayoutEffect, useEffect, useRef } from 'react';
function MyHeavyComponent({ data }) {
const componentId = useRef(`MyHeavyComponent-${Math.random()}`).current;
const markStartName = `${componentId}:render:start`;
const markEndName = `${componentId}:render:end`;
const measureName = `${componentId}:render:duration`;
// useLayoutEffect runs synchronously after all DOM mutations.
// It's the perfect place to mark the start of the render measurement.
useLayoutEffect(() => {
performance.mark(markStartName);
}, []); // Run only on initial mount
// useEffect runs asynchronously after the render is committed to the screen.
// This is a good place to mark the end.
useEffect(() => {
performance.mark(markEndName);
performance.measure(measureName, markStartName, markEndName);
// Log the result for demonstration
const measure = performance.getEntriesByName(measureName)[0];
if (measure) {
console.log(`${measureName} took ${measure.duration}ms`);
}
// Cleanup
performance.clearMarks(markStartName);
performance.clearMarks(markEndName);
performance.clearMeasures(measureName);
}, []); // Run only on initial mount
return (
// ... JSX for the heavy component ...
);
}
۳. کمیسازی سفرهای کاربری حیاتی
تأثیرگذارترین استفاده از User Timing، اندازهگیری تعاملات چند مرحلهای کاربر است که برای کسبوکار شما حیاتی هستند. این فراتر از معیارهای فنی ساده است و سرعت درک شده از قابلیتهای اصلی برنامه شما را اندازهگیری میکند.
یک فرآیند پرداخت در فروشگاه اینترنتی را در نظر بگیرید:
const checkoutButton = document.getElementById('checkout-btn');
checkoutButton.addEventListener('click', () => {
// 1. User clicks the 'checkout' button
performance.mark('checkout:journey:start');
// ... code to validate cart, navigate to payment page, etc. ...
});
// On the payment page, after the payment form is rendered and interactive
function onPaymentFormReady() {
performance.mark('checkout:paymentForm:ready');
performance.measure('checkout:timeToPaymentForm', 'checkout:journey:start', 'checkout:paymentForm:ready');
}
// After the payment is successfully processed and the confirmation screen is shown
function onPaymentSuccess() {
performance.mark('checkout:journey:end');
performance.measure('checkout:totalJourney:duration', 'checkout:journey:start', 'checkout:journey:end');
// Now you have two powerful metrics to analyze and optimize.
}
۴. تست A/B بهبودهای عملکردی
وقتی یک قطعه کد را بازنویسی میکنید یا یک الگوریتم جدید معرفی میکنید، چگونه ثابت میکنید که برای کاربران واقعی سریعتر است؟ User Timing دادههای عینی برای تست A/B فراهم میکند.
تصور کنید دو الگوریتم مرتبسازی مختلف دارید که میخواهید آزمایش کنید:
function sortProducts(products, algorithmVersion) {
const markStart = `sort:v${algorithmVersion}:start`;
const markEnd = `sort:v${algorithmVersion}:end`;
const measureName = `sort:v${algorithmVersion}:duration`;
performance.mark(markStart);
if (algorithmVersion === 'A') {
// ... run old sorting algorithm ...
} else {
// ... run new, optimized sorting algorithm ...
}
performance.mark(markEnd);
performance.measure(measureName, markStart, markEnd);
}
// Based on an A/B testing flag, you would call one or the other.
// Later, in your analytics, you can compare the average duration of
// 'sort:vA:duration' vs 'sort:vB:duration' to see which was faster.
مصورسازی و تحلیل معیارهای سفارشی شما
ایجاد معیارهای سفارشی اگر دادهها را تحلیل نکنید، بیفایده است. دو راه اصلی برای این کار وجود دارد: به صورت محلی در حین توسعه و به صورت تجمیعی در محیط تولید.
استفاده از ابزارهای توسعهدهنده مرورگر
مرورگرهای مدرن مانند Chrome و Firefox پشتیبانی عالی برای مصورسازی نشانهها و اندازهگیریهای User Timing در ابزارهای پروفایل عملکرد خود دارند.
- ابزارهای توسعهدهنده مرورگر خود را باز کنید (F12 یا Ctrl+Shift+I).
- به تب Performance بروید.
- ضبط یک پروفایل را شروع کنید و سپس اقداماتی را در برنامه خود انجام دهید که نشانهها و اندازهگیریهای سفارشی شما را فعال میکنند.
- ضبط را متوقف کنید.
در نمای خط زمانی، یک ردیف اختصاصی به نام Timings خواهید یافت. نشانههای سفارشی شما به صورت خطوط عمودی ظاهر میشوند و اندازهگیریهای شما به صورت نوارهای رنگی که مدت زمانشان را نشان میدهند، نمایش داده میشوند. با بردن ماوس روی آنها، نام و زمان دقیقشان مشخص میشود. این یک روش فوقالعاده قدرتمند برای اشکالزدایی مشکلات عملکردی در حین توسعه است.
ارسال دادهها به سرویسهای تحلیل و RUM
برای نظارت در محیط تولید، شما باید این دادهها را از کاربران خود جمعآوری کرده و برای تجمیع و تحلیل به یک مکان مرکزی ارسال کنید. این بخش اصلی نظارت واقعی کاربر (RUM) است.
گردش کار کلی به این صورت است:
- اندازهگیریهای عملکردی مورد علاقه خود را جمعآوری کنید.
- آنها را به یک بار داده (payload) مناسب فرمت کنید (مثلاً JSON).
- بار داده را به یک نقطه پایانی تحلیلی ارسال کنید. این میتواند یک سرویس شخص ثالث مانند Datadog، New Relic، Sentry یا حتی Google Analytics (از طریق رویدادهای سفارشی) یا یک بکاند سفارشی که شما کنترل میکنید، باشد.
function sendPerformanceData() {
// We only care about our custom application measures
const appMeasures = performance.getEntriesByType('measure').filter(
(entry) => entry.name.startsWith('app:') // Use a naming convention!
);
if (appMeasures.length > 0) {
const payload = JSON.stringify(appMeasures.map(measure => ({
name: measure.name,
duration: measure.duration,
startTime: measure.startTime,
details: measure.detail, // Send our rich context
path: window.location.pathname // Add more context
})));
// Use navigator.sendBeacon for reliable, non-blocking data sending
navigator.sendBeacon('https://analytics.example.com/performance', payload);
// Clean up the measures that have been sent
appMeasures.forEach(measure => {
performance.clearMeasures(measure.name);
// Also clear the associated marks
});
}
}
// Call this function at an appropriate time, e.g., when the page is about to unload
window.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
sendPerformanceData();
}
});
تکنیکهای پیشرفته و بهترین شیوهها
برای تسلط واقعی بر User Timing API، بیایید به برخی ویژگیهای پیشرفته و بهترین شیوهها نگاه کنیم که ابزار دقیق شما را قویتر و کارآمدتر میکند.
استفاده از `PerformanceObserver` برای نظارت ناهمزمان
متدهای `getEntries*()` از شما میخواهند که بافر عملکرد را به صورت دستی بررسی (poll) کنید. این کار دو اشکال دارد: ممکن است بررسی خود را خیلی دیر انجام دهید و ورودیها را از دست بدهید اگر بافر پر شده و پاک شده باشد، و خود بررسی کردن میتواند هزینه عملکردی جزئی داشته باشد. راهحل مدرن و ترجیحی، `PerformanceObserver` است.
یک `PerformanceObserver` به شما امکان میدهد تا در رویدادهای ورودی عملکرد مشترک شوید. تابع بازگشتی (callback) شما به صورت ناهمزمان هر زمان که ورودیهای جدیدی از انواعی که شما مشاهده میکنید ثبت شوند، فراخوانی خواهد شد.
// 1. Create a callback function to handle new entries
const observerCallback = (list) => {
for (const entry of list.getEntries()) {
console.log('New measure observed:', entry.name, entry.duration);
// Here you can immediately send the entry to your analytics service
// without needing to poll or wait.
}
};
// 2. Create the observer instance
const observer = new PerformanceObserver(observerCallback);
// 3. Start observing for 'mark' and 'measure' entry types
// The 'buffered: true' option ensures you get entries that were created
// *before* the observer was registered.
observer.observe({ entryTypes: ['mark', 'measure'], buffered: true });
// Now, any time performance.mark() or performance.measure() is called anywhere
// in your application, the observerCallback will be triggered with the new entry.
// To stop observing later:
// observer.disconnect();
استفاده از `PerformanceObserver` کارآمدتر، قابل اعتمادتر است و باید انتخاب پیشفرض شما برای جمعآوری دادههای عملکردی در یک محیط تولیدی باشد.
یک قرارداد نامگذاری واضح ایجاد کنید
با رشد برنامه شما، معیارهای سفارشی زیادی جمع خواهید کرد. بدون یک قرارداد نامگذاری منسجم، فیلتر کردن و تحلیل دادههای شما دشوار خواهد شد. یک الگو که زمینه را فراهم میکند، اتخاذ کنید.
یک قرارداد خوب میتواند این باشد: [appName]:[featureOrComponent]:[eventName]:[status]
ecom:ProductGallery:render:startecom:ProductGallery:render:endecom:ProductGallery:render:durationadmin:DataTable:fetchApi:startadmin:DataTable:fetchApi:duration
این ساختار فیلتر کردن تمام معیارهای مربوط به `ProductGallery` یا یافتن تمام مدت زمانهای `fetchApi` در کل برنامه را بسیار ساده میکند.
در یک سرویس کمکی انتزاع کنید
برای اطمینان از سازگاری و کاهش کدهای تکراری، فراخوانیهای `performance` را در ماژول یا سرویس کمکی خود بپوشانید. این کار همچنین فعال یا غیرفعال کردن نظارت بر عملکرد را بر اساس محیط آسان میکند.
// performance-service.js
const IS_PERFORMANCE_MONITORING_ENABLED = process.env.NODE_ENV === 'production' || window.location.search.includes('perf=true');
export const perfMark = (name, options) => {
if (!IS_PERFORMANCE_MONITORING_ENABLED) return;
performance.mark(name, options);
};
export const perfMeasure = (name, start, end) => {
if (!IS_PERFORMANCE_MONITORING_ENABLED) return;
performance.measure(name, start, end);
};
export const startJourney = (name) => {
perfMark(`${name}:start`);
};
export const endJourney = (name) => {
const startMark = `${name}:start`;
const endMark = `${name}:end`;
const measureName = `${name}:duration`;
perfMark(endMark);
perfMeasure(measureName, startMark, endMark);
// Optionally clear the marks here
};
// In your component:
// import { startJourney, endJourney } from './performance-service';
// startJourney('ecom:checkout');
// ...later...
// endJourney('ecom:checkout');
نتیجهگیری: کنترل داستان عملکرد برنامه خود را به دست بگیرید
در حالی که معیارهای استاندارد مانند Core Web Vitals یک بررسی سلامت ضروری برای وبسایت شما فراهم میکنند، آنها عملکرد ویژگیها و تعاملاتی را که برنامه شما را منحصربهفرد میسازد، روشن نمیکنند. User Timing API پلی است که این شکاف را پر میکند. این API یک مکانیزم ساده اما عمیقاً قدرتمند برای اندازهگیری آنچه واقعاً برای کاربران و کسبوکار شما اهمیت دارد، فراهم میکند.
با پیادهسازی نشانهها و اندازهگیریهای سفارشی، شما بهینهسازی عملکرد را از یک بازی حدس و گمان به یک علم دادهمحور تبدیل میکنید. شما میتوانید توابع، کامپوننتها یا جریانهای کاربری دقیقی که باعث ایجاد تنگناها میشوند را شناسایی کنید، تأثیر تلاشهای بازنویسی خود را با اعداد عینی تأیید کنید و در نهایت یک تجربه سریعتر و لذتبخشتر برای مخاطبان جهانی خود بسازید.
کوچک شروع کنید. حیاتیترین سفر کاربری در برنامه خود را شناسایی کنید - خواه جستجوی یک محصول، ارسال یک فرم یا بارگذاری یک داشبورد داده باشد. آن را با `performance.mark()` و `performance.measure()` ابزار دقیق کنید. نتایج را در ابزارهای توسعهدهنده خود تحلیل کنید. هنگامی که وضوحی را که فراهم میکند ببینید، قدرت خواهید یافت تا داستان کامل عملکرد برنامه خود را، هر بار با یک معیار سفارشی، روایت کنید.